﻿using DeviceState.DAL;
using DeviceState.Model;
using HDSmartCommunity.BUS;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;

namespace DeviceState
{
    public class RaspberryPie
    {
        public bool SetNtp(string ipAddress)
        {
            try
            {
                RunCommand("chmod 777 /etc/ntp.conf");
                using (FileStream fs = new FileStream("/etc/ntp.conf", FileMode.Open, FileAccess.Write))
                {
                    StreamWriter sw = new StreamWriter(fs);
                    sw.BaseStream.Seek(0, SeekOrigin.Current);
                    sw.WriteLine(string.Format("server {0} prefer", ipAddress));
                    sw.Flush();
                    sw.Close();
                    fs.Close();
                }
                DeviceDAL da = new DeviceDAL();
                da.UpdatNtpServer(ipAddress);

                //RunCommand("reboot");
                return true;
            }
            catch (Exception e)
            {
                LogHelper.Log(e.ToString());
                return false;
            }
        }

        public void RunCommand(string command)
        {
            Process.Start("sudo", command);
        }

        public NetInfo GetNetInfo()
        {
            NetInfo netInfo = new NetInfo();
            StreamReader reader = new StreamReader(@"/etc/dhcpcd.conf", Encoding.Default);
            string theReply = reader.ReadToEnd();
            reader.Close();
            Regex addressRegex = new Regex(@"(?<ip>([^\w\s]+|\s*)static\s*ip_address=\d+.\d+.\d+.\d+/\d+)\s*");
            Regex routerRegex = new Regex(@"(?<router>([^\w\s]+|\s*)static\s*routers=\d+.\d+.\d+.\d+)\s*");
            Regex serverRegex = new Regex(@"(?<server>([^\w\s]+|\s*)static\s*domain_name_servers=\d+.\d+.\d+.\d+)\s*");
            Regex ipRegex = new Regex(@"=\s*(?<ip>\d+.\d+.\d+.\d+)\s*");
            Regex maskReg = new Regex(@"=\s*\d+.\d+.\d+.\d+/(?<mask>\d+)\s*");

            MatchCollection addressCollection = addressRegex.Matches(theReply);
            MatchCollection routerCollection = routerRegex.Matches(theReply);
            MatchCollection serverCollection = serverRegex.Matches(theReply);

            for (int i = 0; i < addressCollection.Count; i++)
            {
                string str = addressCollection[i].Groups["ip"].Value.Trim();
                if (!str.Contains("#"))
                {
                    string ip = ipRegex.Matches(str)[0].Groups["ip"].Value.Trim();
                    netInfo.IP = ip;
                    int mask = Convert.ToInt32(maskReg.Matches(str)[0].Groups["mask"].Value.Trim());
                    netInfo.Mask = GetMask(mask);
                }
            }

            for (int i = 0; i < routerCollection.Count; i++)
            {
                string str = routerCollection[i].Groups["router"].Value.Trim();
                if (!str.Contains("#"))
                {
                    string ip = ipRegex.Matches(str)[0].Groups["ip"].Value.Trim();
                    netInfo.Router = ip;
                }
            }

            for (int i = 0; i < serverCollection.Count; i++)
            {
                string str = serverCollection[i].Groups["server"].Value.Trim();
                if (!str.Contains("#"))
                {
                    string ip = ipRegex.Matches(str)[0].Groups["ip"].Value.Trim();
                    netInfo.Server = ip;
                }
            }

            return netInfo;
        }

        public string GetMask(int value)
        {
            try
            {
                string str = string.Empty;
                for (int i = 0; i < value; i++)
                {
                    str += "1";
                }
                str = str.PadRight(32, '0');
                string a = Convert.ToInt32(str.Substring(0, 8), 2).ToString() + "." + Convert.ToInt32(str.Substring(8, 8), 2).ToString() + "." + Convert.ToInt32(str.Substring(16, 8), 2).ToString() + "." + Convert.ToInt32(str.Substring(24, 8), 2).ToString();
                return a;
            }
            catch
            {
                return "0.0.0.0";
            }
        }


        public bool UpdateNetInfo(NetInfo netInfo)
        {
            try
            {
                RunCommand("chmod 777 /etc/dhcpcd.conf");
                StreamReader reader = new StreamReader(@"/etc/dhcpcd.conf", Encoding.Default);
                string theReply = reader.ReadToEnd();
                reader.Close();

                Regex addressRegex = new Regex(@"(?<address>static\s*ip_address=\d+.\d+.\d+.\d+/\d+)");
                Regex routerRegex = new Regex(@"(?<router>static\s*routers=\d+.\d+.\d+.\d+)");
                Regex serverRegex = new Regex(@"(?<server>static\s*domain_name_servers=\d+.\d+.\d+.\d+)");
                Regex ipRegex = new Regex(@"=\s*(?<ip>\d+.\d+.\d+.\d+)\s*");
                Regex maskRegex = new Regex(@"=\s*(?<mask>\d+.\d+.\d+.\d+/\d+)\s*");

                MatchCollection addressCollection = addressRegex.Matches(theReply);
                MatchCollection routerCollection = routerRegex.Matches(theReply);
                MatchCollection serverCollection = serverRegex.Matches(theReply);

                string value = string.Empty;
                string[] array = netInfo.Mask.Replace(" ", "").Split('.');
                for (int i = 0; i < array.Length; i++)
                {
                    value += Convert.ToString(Convert.ToInt32(array[i]), 2);
                }
                value = value.PadRight(32, '0');

                string keyWord = "1";
                int index = 0;
                int count = 0;
                while ((index = value.IndexOf(keyWord, index)) != -1)
                {
                    count++;
                    index = index + keyWord.Length;
                }

                for (int i = 0; i < addressCollection.Count; i++)
                {
                    string str = addressCollection[i].Groups["address"].Value.Trim();
                    string oldip = maskRegex.Matches(str)[0].Groups["mask"].Value.Trim();
                    string newip = netInfo.IP + "/" + count;
                    if (oldip != newip)
                    {
                        string newstr = str.Replace(oldip, newip);
                        theReply = theReply.Replace(str, newstr);
                    }
                }

                for (int i = 0; i < routerCollection.Count; i++)
                {
                    string str = routerCollection[i].Groups["router"].Value.Trim();
                    string oldip = ipRegex.Matches(str)[0].Groups["ip"].Value.Trim();
                    if (oldip != netInfo.Router)
                    {
                        string newstr = str.Replace(oldip, netInfo.Router);
                        theReply = theReply.Replace(str, newstr);
                    }
                }

                for (int i = 0; i < serverCollection.Count; i++)
                {
                    string str = serverCollection[i].Groups["server"].Value.Trim();
                    string oldip = ipRegex.Matches(str)[0].Groups["ip"].Value.Trim();
                    if (oldip != netInfo.Server)
                    {
                        string newstr = str.Replace(oldip, netInfo.Server);
                        theReply = theReply.Replace(str, newstr);
                    }
                }

                using (FileStream fileStream = new FileStream("/etc/dhcpcd.conf", FileMode.Open, FileAccess.Write, FileShare.Write))
                {
                    fileStream.Seek(0, SeekOrigin.Begin);
                    using (StreamWriter streamWriter = new StreamWriter(fileStream))
                    {
                        streamWriter.Write(theReply);
                        fileStream.Flush();
                        streamWriter.Close();
                    }
                    fileStream.Close();
                }
                RunCommand("reboot");
                return true;
            }
            catch
            {
                return false;
            }
        }

        public bool CalibrationTime(string time)
        {
            try
            {
                RunCommand("date -s \"" + time + "\"");
                return true;
            }
            catch
            {
                return false;
            }
        }

        public string GetNtpIp()
        {
            try
            {
                StreamReader reader = new StreamReader(@"/etc/ntp.conf", Encoding.Default);
                string theReply = reader.ReadToEnd();
                reader.Close();
                Regex addressRegex = new Regex(@"server\s*(?<ip>\d+.\d+.\d+.\d+)\s*prefer");

                MatchCollection addressCollection = addressRegex.Matches(theReply);
                string str = addressCollection[0].Groups["ip"].Value.Trim();

                return str;
            }
            catch
            {
                return "";
            }
        }
    }
}
